package com.linjian.togetherbirthday.view.custab;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.linjian.togetherbirthday.R;
import com.linjian.togetherbirthday.view.custab.listener.OnTabSelectListener;
import com.linjian.togetherbirthday.view.custab.utils.UnreadMsgUtils;
import com.linjian.togetherbirthday.view.custab.widget.MsgView;

import java.util.ArrayList;
import java.util.Collections;

/** 滑动TabLayout,对于ViewPager的依赖性强 */

public class SlidingTabLayout extends HorizontalScrollView implements ViewPager.OnPageChangeListener {

    private Context mContext;

    private ViewPager mViewPager;

    private ArrayList<String> mTitles;

    private LinearLayout mTabsContainer;

    private int mCurrentTab;

    private float mCurrentPositionOffset;

    private int mTabCount;

    /** 用于绘制显示器 */

    private Rect mIndicatorRect = new Rect();

    /** 用于实现滚动居中 */

    private Rect mTabRect = new Rect();

    private GradientDrawable mIndicatorDrawable = new GradientDrawable();



    private Paint mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private Paint mDividerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private Paint mTrianglePaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private Path mTrianglePath = new Path();

    private static final int STYLE_NORMAL = 0;

    private static final int STYLE_TRIANGLE = 1;

    private static final int STYLE_BLOCK = 2;

    private int mIndicatorStyle = STYLE_NORMAL;



    private float mTabPadding;

    private boolean mTabSpaceEqual;

    private float mTabWidth;



    /** indicator */

    private int mIndicatorColor;

    private float mIndicatorHeight;

    private float mIndicatorWidth;

    private float mIndicatorCornerRadius;

    private float mIndicatorMarginLeft;

    private float mIndicatorMarginTop;

    private float mIndicatorMarginRight;

    private float mIndicatorMarginBottom;

    private int mIndicatorGravity;

    private boolean mIndicatorWidthEqualTitle;



    /** underline */

    private int mUnderlineColor;

    private float mUnderlineHeight;

    private int mUnderlineGravity;



    /** divider */

    private int mDividerColor;

    private float mDividerWidth;

    private float mDividerPadding;



    /** title */

    private static final int TEXT_BOLD_NONE = 0;

    private static final int TEXT_BOLD_WHEN_SELECT = 1;

    private static final int TEXT_BOLD_BOTH = 2;

    private float mTextsize;

    private int mTextSelectColor;

    private int mTextUnselectColor;

    private int mTextBold;

    private boolean mTextAllCaps;



    private int mLastScrollX;

    private int mHeight;

    private boolean mSnapOnTabClick;



    public SlidingTabLayout(Context context) {

        this(context, null, 0);

    }



    public SlidingTabLayout(Context context, AttributeSet attrs) {

        this(context, attrs, 0);

    }



    public SlidingTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {

        super(context, attrs, defStyleAttr);

        setFillViewport(true);//设置滚动视图是否可以伸缩其内容以填充视口

        setWillNotDraw(false);//重写onDraw方法,需要调用这个方法来清除flag

        setClipChildren(false);

        setClipToPadding(false);



        this.mContext = context;

        mTabsContainer = new LinearLayout(context);

        addView(mTabsContainer);



        obtainAttributes(context, attrs);



        //get layout_height

        String height = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "layout_height");



        if (height.equals(ViewGroup.LayoutParams.MATCH_PARENT + "")) {

        } else if (height.equals(ViewGroup.LayoutParams.WRAP_CONTENT + "")) {

        } else {

            int[] systemAttrs = {android.R.attr.layout_height};

            TypedArray a = context.obtainStyledAttributes(attrs, systemAttrs);

            mHeight = a.getDimensionPixelSize(0, ViewGroup.LayoutParams.WRAP_CONTENT);

            a.recycle();

        }

    }



    private void obtainAttributes(Context context, AttributeSet attrs) {

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SlidingTabLayout);



        mIndicatorStyle = ta.getInt(R.styleable.SlidingTabLayout_tl_indicator_style, STYLE_NORMAL);

        mIndicatorColor = ta.getColor(R.styleable.SlidingTabLayout_tl_indicator_color, Color.parseColor(mIndicatorStyle == STYLE_BLOCK ? "#4B6A87" : "#ffffff"));

        mIndicatorHeight = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_height,

                dp2px(mIndicatorStyle == STYLE_TRIANGLE ? 4 : (mIndicatorStyle == STYLE_BLOCK ? -1 : 2)));

        mIndicatorWidth = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_width, dp2px(mIndicatorStyle == STYLE_TRIANGLE ? 10 : -1));

        mIndicatorCornerRadius = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_corner_radius, dp2px(mIndicatorStyle == STYLE_BLOCK ? -1 : 0));

        mIndicatorMarginLeft = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_margin_left, dp2px(0));

        mIndicatorMarginTop = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_margin_top, dp2px(mIndicatorStyle == STYLE_BLOCK ? 7 : 0));

        mIndicatorMarginRight = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_margin_right, dp2px(0));

        mIndicatorMarginBottom = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_margin_bottom, dp2px(mIndicatorStyle == STYLE_BLOCK ? 7 : 0));

        mIndicatorGravity = ta.getInt(R.styleable.SlidingTabLayout_tl_indicator_gravity, Gravity.BOTTOM);

        mIndicatorWidthEqualTitle = ta.getBoolean(R.styleable.SlidingTabLayout_tl_indicator_width_equal_title, false);



        mUnderlineColor = ta.getColor(R.styleable.SlidingTabLayout_tl_underline_color, Color.parseColor("#ffffff"));

        mUnderlineHeight = ta.getDimension(R.styleable.SlidingTabLayout_tl_underline_height, dp2px(0));

        mUnderlineGravity = ta.getInt(R.styleable.SlidingTabLayout_tl_underline_gravity, Gravity.BOTTOM);



        mDividerColor = ta.getColor(R.styleable.SlidingTabLayout_tl_divider_color, Color.parseColor("#ffffff"));

        mDividerWidth = ta.getDimension(R.styleable.SlidingTabLayout_tl_divider_width, dp2px(0));

        mDividerPadding = ta.getDimension(R.styleable.SlidingTabLayout_tl_divider_padding, dp2px(12));



        mTextsize = ta.getDimension(R.styleable.SlidingTabLayout_tl_textsize, sp2px(14));

        mTextSelectColor = ta.getColor(R.styleable.SlidingTabLayout_tl_textSelectColor, Color.parseColor("#ffffff"));

        mTextUnselectColor = ta.getColor(R.styleable.SlidingTabLayout_tl_textUnselectColor, Color.parseColor("#AAffffff"));

        mTextBold = ta.getInt(R.styleable.SlidingTabLayout_tl_textBold, TEXT_BOLD_NONE);

        mTextAllCaps = ta.getBoolean(R.styleable.SlidingTabLayout_tl_textAllCaps, false);



        mTabSpaceEqual = ta.getBoolean(R.styleable.SlidingTabLayout_tl_tab_space_equal, false);

        mTabWidth = ta.getDimension(R.styleable.SlidingTabLayout_tl_tab_width, dp2px(-1));

        mTabPadding = ta.getDimension(R.styleable.SlidingTabLayout_tl_tab_padding, mTabSpaceEqual || mTabWidth > 0 ? dp2px(0) : dp2px(20));



        ta.recycle();

    }



    /** 关联ViewPager */

    public void setViewPager(ViewPager vp) {

        if (vp == null || vp.getAdapter() == null) {
            throw new IllegalStateException("ViewPager or ViewPager adapter can not be NULL !");
        }



        this.mViewPager = vp;



        this.mViewPager.removeOnPageChangeListener(this);

        this.mViewPager.addOnPageChangeListener(this);

        notifyDataSetChanged();

    }



    /** 关联ViewPager,用于不想在ViewPager适配器中设置titles数据的情况 */

    public void setViewPager(ViewPager vp, String[] titles) {

        if (vp == null || vp.getAdapter() == null) {

            throw new IllegalStateException("ViewPager or ViewPager adapter can not be NULL !");

        }



        if (titles == null || titles.length == 0) {

            throw new IllegalStateException("Titles can not be EMPTY !");

        }



        if (titles.length != vp.getAdapter().getCount()) {

            throw new IllegalStateException("Titles length must be the same as the page count !");

        }



        this.mViewPager = vp;

        mTitles = new ArrayList<>();

        Collections.addAll(mTitles, titles);



        this.mViewPager.removeOnPageChangeListener(this);

        this.mViewPager.addOnPageChangeListener(this);

        notifyDataSetChanged();

    }



    /** 关联ViewPager,用于连适配器都不想自己实例化的情况 */

    public void setViewPager(ViewPager vp, String[] titles, FragmentActivity fa, ArrayList<Fragment> fragments) {

        if (vp == null) {

            throw new IllegalStateException("ViewPager can not be NULL !");

        }



        if (titles == null || titles.length == 0) {

            throw new IllegalStateException("Titles can not be EMPTY !");

        }



        this.mViewPager = vp;

        this.mViewPager.setAdapter(new InnerPagerAdapter(fa.getSupportFragmentManager(), fragments, titles));



        this.mViewPager.removeOnPageChangeListener(this);

        this.mViewPager.addOnPageChangeListener(this);

        notifyDataSetChanged();

    }



    /** 更新数据 */

    public void notifyDataSetChanged() {

        mTabsContainer.removeAllViews();

        this.mTabCount = mTitles == null ? mViewPager.getAdapter().getCount() : mTitles.size();

        View tabView;

        for (int i = 0; i < mTabCount; i++) {

            tabView = View.inflate(mContext, R.layout.layout_tab, null);

            CharSequence pageTitle = mTitles == null ? mViewPager.getAdapter().getPageTitle(i) : mTitles.get(i);

            addTab(i, pageTitle.toString(), tabView);

        }



        updateTabStyles();

    }



    public void addNewTab(String title) {

        View tabView = View.inflate(mContext, R.layout.layout_tab, null);

        if (mTitles != null) {

            mTitles.add(title);

        }



        CharSequence pageTitle = mTitles == null ? mViewPager.getAdapter().getPageTitle(mTabCount) : mTitles.get(mTabCount);

        addTab(mTabCount, pageTitle.toString(), tabView);

        this.mTabCount = mTitles == null ? mViewPager.getAdapter().getCount() : mTitles.size();



        updateTabStyles();

    }



    /** 创建并添加tab */

    private void addTab(final int position, String title, View tabView) {

        TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);

        if (tv_tab_title != null) {

            if (title != null) tv_tab_title.setText(title);

        }



        tabView.setOnClickListener(new OnClickListener() {

            @Override

            public void onClick(View v) {

                int position = mTabsContainer.indexOfChild(v);

                if (position != -1) {

                    if (mViewPager.getCurrentItem() != position) {

                        if (mSnapOnTabClick) {

                            mViewPager.setCurrentItem(position, false);

                        } else {

                            mViewPager.setCurrentItem(position);

                        }



                        if (mListener != null) {

                            mListener.onTabSelect(position);

                        }

                    } else {

                        if (mListener != null) {

                            mListener.onTabReselect(position);

                        }

                    }

                }

            }

        });



        /** 每一个Tab的布局参数 */

        LinearLayout.LayoutParams lp_tab = mTabSpaceEqual ?

                new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f) :

                new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);

        if (mTabWidth > 0) {

            lp_tab = new LinearLayout.LayoutParams((int) mTabWidth, LayoutParams.MATCH_PARENT);

        }



        mTabsContainer.addView(tabView, position, lp_tab);

    }



    private void updateTabStyles() {

        for (int i = 0; i < mTabCount; i++) {

            View v = mTabsContainer.getChildAt(i);

//            v.setPadding((int) mTabPadding, v.getPaddingTop(), (int) mTabPadding, v.getPaddingBottom());

            TextView tv_tab_title = (TextView) v.findViewById(R.id.tv_tab_title);

            if (tv_tab_title != null) {

                tv_tab_title.setTextColor(i == mCurrentTab ? mTextSelectColor : mTextUnselectColor);

                tv_tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextsize);

                tv_tab_title.setPadding((int) mTabPadding, 0, (int) mTabPadding, 0);

                if (mTextAllCaps) {

                    tv_tab_title.setText(tv_tab_title.getText().toString().toUpperCase());

                }



                if (mTextBold == TEXT_BOLD_BOTH) {

                    tv_tab_title.getPaint().setFakeBoldText(true);

                } else if (mTextBold == TEXT_BOLD_NONE) {

                    tv_tab_title.getPaint().setFakeBoldText(false);

                }

            }

        }

    }



    @Override

    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        /**

         * position:当前View的位置

         * mCurrentPositionOffset:当前View的偏移量比例.[0,1)

         */

        this.mCurrentTab = position;

        this.mCurrentPositionOffset = positionOffset;

        scrollToCurrentTab();

        invalidate();

    }



    @Override

    public void onPageSelected(int position) {

        updateTabSelection(position);

    }



    @Override

    public void onPageScrollStateChanged(int state) {

    }



    /** HorizontalScrollView滚到当前tab,并且居中显示 */

    private void scrollToCurrentTab() {

        if (mTabCount <= 0) {

            return;

        }



        int offset = (int) (mCurrentPositionOffset * mTabsContainer.getChildAt(mCurrentTab).getWidth());

        /**当前Tab的left+当前Tab的Width乘以positionOffset*/

        int newScrollX = mTabsContainer.getChildAt(mCurrentTab).getLeft() + offset;



        if (mCurrentTab > 0 || offset > 0) {

            /**HorizontalScrollView移动到当前tab,并居中*/

            newScrollX -= getWidth() / 2 - getPaddingLeft();

            calcIndicatorRect();

            newScrollX += ((mTabRect.right - mTabRect.left) / 2);

        }



        if (newScrollX != mLastScrollX) {

            mLastScrollX = newScrollX;

            /** scrollTo（int x,int y）:x,y代表的不是坐标点,而是偏移量

             *  x:表示离起始位置的x水平方向的偏移量

             *  y:表示离起始位置的y垂直方向的偏移量

             */

            scrollTo(newScrollX, 0);

        }

    }



    private void updateTabSelection(int position) {

        for (int i = 0; i < mTabCount; ++i) {

            View tabView = mTabsContainer.getChildAt(i);

            final boolean isSelect = i == position;

            TextView tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);



            if (tab_title != null) {

                tab_title.setTextColor(isSelect ? mTextSelectColor : mTextUnselectColor);

                if (mTextBold == TEXT_BOLD_WHEN_SELECT) {

                    tab_title.getPaint().setFakeBoldText(isSelect);

                }

            }

        }

    }



    private float margin;



    private void calcIndicatorRect() {

        View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);

        float left = currentTabView.getLeft();

        float right = currentTabView.getRight();



        //for mIndicatorWidthEqualTitle

        if (mIndicatorStyle == STYLE_NORMAL && mIndicatorWidthEqualTitle) {

            TextView tab_title = (TextView) currentTabView.findViewById(R.id.tv_tab_title);

            mTextPaint.setTextSize(mTextsize);

            float textWidth = mTextPaint.measureText(tab_title.getText().toString());

            margin = (right - left - textWidth) / 2;

        }



        if (this.mCurrentTab < mTabCount - 1) {

            View nextTabView = mTabsContainer.getChildAt(this.mCurrentTab + 1);

            float nextTabLeft = nextTabView.getLeft();

            float nextTabRight = nextTabView.getRight();



            left = left + mCurrentPositionOffset * (nextTabLeft - left);

            right = right + mCurrentPositionOffset * (nextTabRight - right);



            //for mIndicatorWidthEqualTitle

            if (mIndicatorStyle == STYLE_NORMAL && mIndicatorWidthEqualTitle) {

                TextView next_tab_title = (TextView) nextTabView.findViewById(R.id.tv_tab_title);

                mTextPaint.setTextSize(mTextsize);

                float nextTextWidth = mTextPaint.measureText(next_tab_title.getText().toString());

                float nextMargin = (nextTabRight - nextTabLeft - nextTextWidth) / 2;

                margin = margin + mCurrentPositionOffset * (nextMargin - margin);

            }

        }



        mIndicatorRect.left = (int) left;

        mIndicatorRect.right = (int) right;

        //for mIndicatorWidthEqualTitle

        if (mIndicatorStyle == STYLE_NORMAL && mIndicatorWidthEqualTitle) {

            mIndicatorRect.left = (int) (left + margin - 1);

            mIndicatorRect.right = (int) (right - margin - 1);

        }



        mTabRect.left = (int) left;

        mTabRect.right = (int) right;



        if (mIndicatorWidth < 0) {   //indicatorWidth小于0时,原jpardogo's PagerSlidingTabStrip



        } else {//indicatorWidth大于0时,圆角矩形以及三角形

            float indicatorLeft = currentTabView.getLeft() + (currentTabView.getWidth() - mIndicatorWidth) / 2;



            if (this.mCurrentTab < mTabCount - 1) {

                View nextTab = mTabsContainer.getChildAt(this.mCurrentTab + 1);

                indicatorLeft = indicatorLeft + mCurrentPositionOffset * (currentTabView.getWidth() / 2 + nextTab.getWidth() / 2);

            }



            mIndicatorRect.left = (int) indicatorLeft;

            mIndicatorRect.right = (int) (mIndicatorRect.left + mIndicatorWidth);

        }

    }



    @Override

    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);



        if (isInEditMode() || mTabCount <= 0) {

            return;

        }



        int height = getHeight();

        int paddingLeft = getPaddingLeft();

        // draw divider

        if (mDividerWidth > 0) {

            mDividerPaint.setStrokeWidth(mDividerWidth);

            mDividerPaint.setColor(mDividerColor);

            for (int i = 0; i < mTabCount - 1; i++) {

                View tab = mTabsContainer.getChildAt(i);

                canvas.drawLine(paddingLeft + tab.getRight(), mDividerPadding, paddingLeft + tab.getRight(), height - mDividerPadding, mDividerPaint);

            }

        }



        // draw underline

        if (mUnderlineHeight > 0) {

            mRectPaint.setColor(mUnderlineColor);

            if (mUnderlineGravity == Gravity.BOTTOM) {

                canvas.drawRect(paddingLeft, height - mUnderlineHeight, mTabsContainer.getWidth() + paddingLeft, height, mRectPaint);

            } else {

                canvas.drawRect(paddingLeft, 0, mTabsContainer.getWidth() + paddingLeft, mUnderlineHeight, mRectPaint);

            }

        }



        //draw indicator line



        calcIndicatorRect();

        if (mIndicatorStyle == STYLE_TRIANGLE) {

            if (mIndicatorHeight > 0) {

                mTrianglePaint.setColor(mIndicatorColor);

                mTrianglePath.reset();

                mTrianglePath.moveTo(paddingLeft + mIndicatorRect.left, height);

                mTrianglePath.lineTo(paddingLeft + mIndicatorRect.left / 2 + mIndicatorRect.right / 2, height - mIndicatorHeight);

                mTrianglePath.lineTo(paddingLeft + mIndicatorRect.right, height);

                mTrianglePath.close();

                canvas.drawPath(mTrianglePath, mTrianglePaint);

            }

        } else if (mIndicatorStyle == STYLE_BLOCK) {

            if (mIndicatorHeight < 0) {

                mIndicatorHeight = height - mIndicatorMarginTop - mIndicatorMarginBottom;

            } else {



            }



            if (mIndicatorHeight > 0) {

                if (mIndicatorCornerRadius < 0 || mIndicatorCornerRadius > mIndicatorHeight / 2) {

                    mIndicatorCornerRadius = mIndicatorHeight / 2;

                }



                mIndicatorDrawable.setColor(mIndicatorColor);

                mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,

                        (int) mIndicatorMarginTop, (int) (paddingLeft + mIndicatorRect.right - mIndicatorMarginRight),

                        (int) (mIndicatorMarginTop + mIndicatorHeight));

                mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);

                mIndicatorDrawable.draw(canvas);

            }

        } else {

               /* mRectPaint.setColor(mIndicatorColor);

                calcIndicatorRect();

                canvas.drawRect(getPaddingLeft() + mIndicatorRect.left, getHeight() - mIndicatorHeight,

                        mIndicatorRect.right + getPaddingLeft(), getHeight(), mRectPaint);*/



            if (mIndicatorHeight > 0) {

                mIndicatorDrawable.setColor(mIndicatorColor);



                if (mIndicatorGravity == Gravity.BOTTOM) {

                    mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,

                            height - (int) mIndicatorHeight - (int) mIndicatorMarginBottom,

                            paddingLeft + mIndicatorRect.right - (int) mIndicatorMarginRight,

                            height - (int) mIndicatorMarginBottom);

                } else {

                    mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,

                            (int) mIndicatorMarginTop,

                            paddingLeft + mIndicatorRect.right - (int) mIndicatorMarginRight,

                            (int) mIndicatorHeight + (int) mIndicatorMarginTop);

                }

                mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);

                mIndicatorDrawable.draw(canvas);

            }

        }

    }



    //setter and getter

    public void setCurrentTab(int currentTab) {

        this.mCurrentTab = currentTab;

        mViewPager.setCurrentItem(currentTab);



    }



    public void setCurrentTab(int currentTab, boolean smoothScroll) {

        this.mCurrentTab = currentTab;

        mViewPager.setCurrentItem(currentTab, smoothScroll);

    }



    public void setIndicatorStyle(int indicatorStyle) {

        this.mIndicatorStyle = indicatorStyle;

        invalidate();

    }



    public void setTabPadding(float tabPadding) {

        this.mTabPadding = dp2px(tabPadding);

        updateTabStyles();

    }



    public void setTabSpaceEqual(boolean tabSpaceEqual) {

        this.mTabSpaceEqual = tabSpaceEqual;

        updateTabStyles();

    }



    public void setTabWidth(float tabWidth) {

        this.mTabWidth = dp2px(tabWidth);

        updateTabStyles();

    }



    public void setIndicatorColor(int indicatorColor) {

        this.mIndicatorColor = indicatorColor;

        invalidate();

    }



    public void setIndicatorHeight(float indicatorHeight) {

        this.mIndicatorHeight = dp2px(indicatorHeight);

        invalidate();

    }



    public void setIndicatorWidth(float indicatorWidth) {

        this.mIndicatorWidth = dp2px(indicatorWidth);

        invalidate();

    }



    public void setIndicatorCornerRadius(float indicatorCornerRadius) {

        this.mIndicatorCornerRadius = dp2px(indicatorCornerRadius);

        invalidate();

    }



    public void setIndicatorGravity(int indicatorGravity) {

        this.mIndicatorGravity = indicatorGravity;

        invalidate();

    }



    public void setIndicatorMargin(float indicatorMarginLeft, float indicatorMarginTop,

                                   float indicatorMarginRight, float indicatorMarginBottom) {

        this.mIndicatorMarginLeft = dp2px(indicatorMarginLeft);

        this.mIndicatorMarginTop = dp2px(indicatorMarginTop);

        this.mIndicatorMarginRight = dp2px(indicatorMarginRight);

        this.mIndicatorMarginBottom = dp2px(indicatorMarginBottom);

        invalidate();

    }



    public void setIndicatorWidthEqualTitle(boolean indicatorWidthEqualTitle) {

        this.mIndicatorWidthEqualTitle = indicatorWidthEqualTitle;

        invalidate();

    }



    public void setUnderlineColor(int underlineColor) {

        this.mUnderlineColor = underlineColor;

        invalidate();

    }



    public void setUnderlineHeight(float underlineHeight) {

        this.mUnderlineHeight = dp2px(underlineHeight);

        invalidate();

    }



    public void setUnderlineGravity(int underlineGravity) {

        this.mUnderlineGravity = underlineGravity;

        invalidate();

    }



    public void setDividerColor(int dividerColor) {

        this.mDividerColor = dividerColor;

        invalidate();

    }



    public void setDividerWidth(float dividerWidth) {

        this.mDividerWidth = dp2px(dividerWidth);

        invalidate();

    }



    public void setDividerPadding(float dividerPadding) {

        this.mDividerPadding = dp2px(dividerPadding);

        invalidate();

    }



    public void setTextsize(float textsize) {

        this.mTextsize = sp2px(textsize);

        updateTabStyles();

    }



    public void setTextSelectColor(int textSelectColor) {

        this.mTextSelectColor = textSelectColor;

        updateTabStyles();

    }



    public void setTextUnselectColor(int textUnselectColor) {

        this.mTextUnselectColor = textUnselectColor;

        updateTabStyles();

    }



    public void setTextBold(int textBold) {

        this.mTextBold = textBold;

        updateTabStyles();

    }



    public void setTextAllCaps(boolean textAllCaps) {

        this.mTextAllCaps = textAllCaps;

        updateTabStyles();

    }



    public void setSnapOnTabClick(boolean snapOnTabClick) {

        mSnapOnTabClick = snapOnTabClick;

    }





    public int getTabCount() {

        return mTabCount;

    }



    public int getCurrentTab() {

        return mCurrentTab;

    }



    public int getIndicatorStyle() {

        return mIndicatorStyle;

    }



    public float getTabPadding() {

        return mTabPadding;

    }



    public boolean isTabSpaceEqual() {

        return mTabSpaceEqual;

    }



    public float getTabWidth() {

        return mTabWidth;

    }



    public int getIndicatorColor() {

        return mIndicatorColor;

    }



    public float getIndicatorHeight() {

        return mIndicatorHeight;

    }



    public float getIndicatorWidth() {

        return mIndicatorWidth;

    }



    public float getIndicatorCornerRadius() {

        return mIndicatorCornerRadius;

    }



    public float getIndicatorMarginLeft() {

        return mIndicatorMarginLeft;

    }



    public float getIndicatorMarginTop() {

        return mIndicatorMarginTop;

    }



    public float getIndicatorMarginRight() {

        return mIndicatorMarginRight;

    }



    public float getIndicatorMarginBottom() {

        return mIndicatorMarginBottom;

    }



    public int getUnderlineColor() {

        return mUnderlineColor;

    }



    public float getUnderlineHeight() {

        return mUnderlineHeight;

    }



    public int getDividerColor() {

        return mDividerColor;

    }



    public float getDividerWidth() {

        return mDividerWidth;

    }



    public float getDividerPadding() {

        return mDividerPadding;

    }



    public float getTextsize() {

        return mTextsize;

    }



    public int getTextSelectColor() {

        return mTextSelectColor;

    }



    public int getTextUnselectColor() {

        return mTextUnselectColor;

    }



    public int getTextBold() {

        return mTextBold;

    }



    public boolean isTextAllCaps() {

        return mTextAllCaps;

    }



    public TextView getTitleView(int tab) {

        View tabView = mTabsContainer.getChildAt(tab);

        TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);

        return tv_tab_title;

    }



    //setter and getter



    // show MsgTipView

    private Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private SparseArray<Boolean> mInitSetMap = new SparseArray<>();



    /**

     * 显示未读消息

     *

     * @param position 显示tab位置

     * @param num      num小于等于0显示红点,num大于0显示数字

     */

    public void showMsg(int position, int num) {

        if (position >= mTabCount) {

            position = mTabCount - 1;

        }



        View tabView = mTabsContainer.getChildAt(position);

        MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);

        if (tipView != null) {

            UnreadMsgUtils.show(tipView, num);



            if (mInitSetMap.get(position) != null && mInitSetMap.get(position)) {

                return;

            }



            setMsgMargin(position, 4, 2);

            mInitSetMap.put(position, true);

        }

    }



    /**

     * 显示未读红点

     *

     * @param position 显示tab位置

     */

    public void showDot(int position) {

        if (position >= mTabCount) {

            position = mTabCount - 1;

        }

        showMsg(position, 0);

    }



    /** 隐藏未读消息 */

    public void hideMsg(int position) {

        if (position >= mTabCount) {

            position = mTabCount - 1;

        }



        View tabView = mTabsContainer.getChildAt(position);

        MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);

        if (tipView != null) {

            tipView.setVisibility(View.GONE);

        }

    }



    /** 设置未读消息偏移,原点为文字的右上角.当控件高度固定,消息提示位置易控制,显示效果佳 */

    public void setMsgMargin(int position, float leftPadding, float bottomPadding) {

        if (position >= mTabCount) {

            position = mTabCount - 1;

        }

        View tabView = mTabsContainer.getChildAt(position);

        MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);

        if (tipView != null) {

            TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);

            mTextPaint.setTextSize(mTextsize);

            float textWidth = mTextPaint.measureText(tv_tab_title.getText().toString());

            float textHeight = mTextPaint.descent() - mTextPaint.ascent();

            MarginLayoutParams lp = (MarginLayoutParams) tipView.getLayoutParams();

            lp.leftMargin = mTabWidth >= 0 ? (int) (mTabWidth / 2 + textWidth / 2 + dp2px(leftPadding)) : (int) (mTabPadding + textWidth + dp2px(leftPadding));

            lp.topMargin = mHeight > 0 ? (int) (mHeight - textHeight) / 2 - dp2px(bottomPadding) : 0;

            tipView.setLayoutParams(lp);

        }

    }



    /** 当前类只提供了少许设置未读消息属性的方法,可以通过该方法获取MsgView对象从而各种设置 */

    public MsgView getMsgView(int position) {

        if (position >= mTabCount) {

            position = mTabCount - 1;

        }

        View tabView = mTabsContainer.getChildAt(position);

        MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);

        return tipView;

    }



    private OnTabSelectListener mListener;



    public void setOnTabSelectListener(OnTabSelectListener listener) {

        this.mListener = listener;

    }



    class InnerPagerAdapter extends FragmentPagerAdapter {

        private ArrayList<Fragment> fragments = new ArrayList<>();

        private String[] titles;



        public InnerPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragments, String[] titles) {

            super(fm);

            this.fragments = fragments;

            this.titles = titles;

        }



        @Override

        public int getCount() {

            return fragments.size();

        }



        @Override

        public CharSequence getPageTitle(int position) {

            return titles[position];

        }



        @Override

        public Fragment getItem(int position) {

            return fragments.get(position);

        }



        @Override

        public void destroyItem(ViewGroup container, int position, Object object) {

            // 覆写destroyItem并且空实现,这样每个Fragment中的视图就不会被销毁

            // super.destroyItem(container, position, object);

        }



        @Override

        public int getItemPosition(Object object) {

            return PagerAdapter.POSITION_NONE;

        }

    }



    @Override

    protected Parcelable onSaveInstanceState() {

        Bundle bundle = new Bundle();

        bundle.putParcelable("instanceState", super.onSaveInstanceState());

        bundle.putInt("mCurrentTab", mCurrentTab);

        return bundle;

    }



    @Override

    protected void onRestoreInstanceState(Parcelable state) {

        if (state instanceof Bundle) {

            Bundle bundle = (Bundle) state;

            mCurrentTab = bundle.getInt("mCurrentTab");

            state = bundle.getParcelable("instanceState");

            if (mCurrentTab != 0 && mTabsContainer.getChildCount() > 0) {

                updateTabSelection(mCurrentTab);

                scrollToCurrentTab();

            }

        }

        super.onRestoreInstanceState(state);

    }



    protected int dp2px(float dp) {

        final float scale = mContext.getResources().getDisplayMetrics().density;

        return (int) (dp * scale + 0.5f);

    }



    protected int sp2px(float sp) {

        final float scale = this.mContext.getResources().getDisplayMetrics().scaledDensity;

        return (int) (sp * scale + 0.5f);

    }

}
